package cn.example.util.toolkit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * IO工具类
 * Created by WuYB on 2017/4/27.
 */
public class IOUtil {

    private static Logger log = LoggerFactory.getLogger(IOUtil.class);

    private static class SingletonHolder {
        private static final IOUtil INSTANCE = new IOUtil();
    }

    private IOUtil() {
    }

    public static IOUtil getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 输入流转字符串
     *
     * @param inputStream 输入流
     * @return String
     */
    public String inputStream2Str(InputStream inputStream) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String str = null;
        StringBuilder builder = new StringBuilder();
        while ((str = bufferedReader.readLine()) != null) {
            builder.append(str);
        }
        bufferedReader.close();
        inputStreamReader.close();
        return builder.toString();
    }

    /**
     * 删除当前文件夹/文件
     *
     * @param file 文件
     */
    public void deleteAll(File file) {
        if (file.isFile()) {
            file.delete();
        } else {
            File files[] = file.listFiles();
            for (File ff : files) {
                deleteAll(ff);
            }
            file.delete();
        }

    }

    /**
     * 删除当前文件
     *
     * @param file 文件
     */
    public boolean deleteFile(File file) {
        return file.isFile() && file.delete();
    }

    /**
     * 文件拷贝（指定编码）
     *
     * @param source         原文件
     * @param into           目标文件
     * @param sourceEncoding 源文件编码格式
     * @param intoEncode     目标文件编码格式
     * @return boolean
     */
    public boolean copy(File source, File into, String sourceEncoding, String intoEncode) {
        try {
            FileInputStream fis = new FileInputStream(source);
            FileOutputStream fos = new FileOutputStream(into);
            InputStreamReader isr = new InputStreamReader(fis, sourceEncoding);
            OutputStreamWriter osw = new OutputStreamWriter(fos, intoEncode);
            char b[] = new char[1024 * 1024];
            int len = 0;
            while ((len = isr.read(b)) != -1) {
                osw.write(b, 0, len);
            }
            osw.flush();
            // 先关输出流，再关输入流
            osw.close();
            fos.close();
            isr.close();
            fis.close();
            return true;
        } catch (IOException e) {
            log.error("File Copy Error!", e);
            return false;
        }
    }

    /**
     * 文件拷贝（按路径）
     *
     * @param from           原文件路径
     * @param into           目标文件路径
     * @param sourceEncoding 原文件编码格式
     * @param intoEncode     目标文件编码格式
     * @return boolean
     */
    public boolean copy(String from, String into, String sourceEncoding, String intoEncode) {
        String dirFrom = "";
        if (from.endsWith("/")) {
            dirFrom = dirFrom + from;
        } else {
            dirFrom = dirFrom + "/" + from;
        }
        String dirInto = "";
        if (into.endsWith("/")) {
            dirInto = dirInto + into;
        } else {
            dirInto = dirInto + into;
        }
        return copy(new File(dirFrom), new File(dirInto), sourceEncoding, intoEncode);
    }

    /**
     * 序列化某个对象
     *
     * @param obj      需要被序列化的对象
     * @param filePath 序列化后保存地址
     * @return boolean
     */
    public boolean seril(Object obj, String filePath) {
        try {
            FileOutputStream fos = new FileOutputStream(filePath);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(obj);
            oos.close();
            fos.close();
            return true;
        } catch (IOException e) {
            log.error("Object Serialization Error!", e);
            return false;
        }
    }

    /**
     * 反序列化，返回一个Object对象
     *
     * @param filePath 目标路径
     * @return Object
     */
    public Object reSeril(String filePath) {
        try {
            FileInputStream fis = new FileInputStream(filePath);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object obj = ois.readObject();
            ois.close();
            fis.close();
            return obj;
        } catch (IOException | ClassNotFoundException e) {
            log.error("File Deserialization Error!", e);
            return null;
        }
    }

    /**
     * 复制二进制文件
     *
     * @param source 原文件
     * @param into   目标文件
     * @return boolean
     */
    public boolean copydata(File source, File into) {
        try {
            //构建二进制文件输入流
            FileInputStream fis = new FileInputStream(source);
            DataInputStream dis = new DataInputStream(fis);
            //构建二进制文件输出流
            FileOutputStream fos = new FileOutputStream(into);
            DataOutputStream dos = new DataOutputStream(fos);
            //读写文件
            int len;
            while ((len = dis.read()) != -1) {
                dos.write(len);
            }
            //关闭流
            dos.close();
            fos.close();
            dis.close();
            fis.close();
            return true;
        } catch (IOException e) {
            log.error("Date Copy Error!", e);
            return false;
        }
    }

}
